Note: The group functions in the PVM version of the program are not necessary in the MPI counterpart, since the basic group corresponding to MPI_COMM_WORLD containing all the tasks already exists in MPI.
/* * SPMD example using PVM 3 * also illustrating group functions */ #define NPROC 4 #include <stdio.h> #include <sys/types.h> #include "pvm3.h" void dowork(int me, int nproc); main() { int mytid; /* my task id */ int tids[NPROC]; /* array of task id */ int me; /* my process number */ int i; /* enroll in pvm */ mytid = pvm_mytid(); /* Join a group and if I am the first instance */ /* i.e. me=0 spawn more copies of myself */ me = pvm_joingroup("foo"); printf("me = %d mytid = %d\n",me,mytid); if( me == 0 ) pvm_spawn("spmd", (char**)0, 0, "", NPROC-1,&tids[1]); /* Wait for everyone to startup before proceeding. */ pvm_barrier("foo", NPROC); /*------------------------------------------------------*/ dowork(me, NPROC); /* Program finished. Leave group and exit pvm */ pvm_lvgroup("foo"); pvm_exit(); exit(1); } /* Simple example passes a token around a ring */ void dowork(int me, int nproc) { int token; int src, dest; int count = 1; int stride = 1; int msgtag = 4; /* Determine neighbors in the ring */ src = pvm_gettid("foo", me-1); dest= pvm_gettid("foo", me+1); if(me == 0) src = pvm_gettid("foo", NPROC-1); if(me == NPROC-1) dest = pvm_gettid("foo", 0); if(me == 0) { token = dest; pvm_initsend(PvmDataDefault); pvm_pkint(&token, count, stride); pvm_send(dest, msgtag); printf("token ring begun: value sent = %d\n", token); pvm_recv(src, msgtag); pvm_upkint(&token, count, stride); printf("token ring done: value recvd = %d\n", token); } else { pvm_recv(src, msgtag); pvm_upkint(&token, count, stride); pvm_initsend(PvmDataDefault); pvm_pkint(&token, count, stride); pvm_send(dest, msgtag); } }
/* * SPMD example using MPI, * illustrating porting from PVM to MPI. */ #include <stdio.h> #include <sys/types.h> #include <mpi.h> void dowork(int me, int nproc); main(int argc, char *argv[]) { int mytid; /* my task id */ int ntasks; /* total number of tasks */ int i; /* Initialize MPI */ MPI_Init(&argc, &argv); /* Get our task id (our rank in the basic group) */ MPI_Comm_rank(MPI_COMM_WORLD, &mytid); /* Get the number of MPI tasks */ MPI_Comm_size(MPI_COMM_WORLD, &ntasks); if(mytid == 0) printf("mytid = %d, ntasks = %d\n", mytid, ntasks); /* Wait for everyone to startup before proceeding. */ MPI_Barrier(MPI_COMM_WORLD); /*-------------------------------------------------*/ dowork(mytid, ntasks); MPI_Finalize(); exit(0); } /* Simple example passes a token around a ring */ void dowork(int me, int nproc) { int token; int src, dest; MPI_Status status; int count = 1; int msgtag = 4; /* Determine neighbors in the ring */ src = me-1; dest= me+1; if(me == 0) src = nproc-1; if(me == nproc-1) dest = 0; if(me == 0) { token = dest; MPI_Send(&token, count, MPI_INT, dest, msgtag, MPI_COMM_WORLD); printf("token ring begun: value sent = %d\n", token); MPI_Recv(&token, count, MPI_INT, src, msgtag, MPI_COMM_WORLD, &status); printf("token ring done: value rcvd = %d\n", token); } else { MPI_Recv(&token, count, MPI_INT, src, msgtag, MPI_COMM_WORLD, &status); MPI_Send(&token, count, MPI_INT, dest, msgtag, MPI_COMM_WORLD); } }